//---------------------------------------------------------------------
// File: XmlValidateStep
// 
// Summary: 
//
// Copyright (c) Hammersmith & Fulham Bridge Partnership. All rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Xml;
using Microsoft.Services.BizTalkApplicationFramework.BizUnit;
using BizUnitExtensions.Utilities;
using System.Xml.Schema;
using System.Collections;
using System.IO;
using System.Text;

namespace BizUnit.Extensions
{
    /// <summary>
    /// </summary>
    /// <remarks>
    /// The following shows an example of the Xml representation of this test step.
    /// 
    /// <code escaped="true">
    /// <TestStep assemblyPath="BizUnit.Extensions.dll" typeName="BizUnit.Extensions.XmlValidateStep">
    /// <InputFileName></InputFileName>
    /// <SchemaFiles>
    ///		<SchemaFile namespaceAlias="ns1" takeFromCtx="CINSPersonCreated"></SchemaFile>
    ///     <SchemaFile namespaceAlias="ns2" takeFromCtx="PersonNameDescriptives"></SchemaFiles>
    /// </SchemaFiles>
    /// <ValidationStep assemblyPath="" typeName="Microsoft.Services.BizTalkApplicationFramework.BizUnit.ContextValidationStep">
	///		<Context keyName="XmlValidateStepErrorCount">0</Context>
	///	</ValidationStep>
    /// </TestStep>
    ///	</code>
    ///	
    ///	<list type="table">
    ///		<listheader>
    ///			<term>Tag</term>
    ///			<description>Description</description>
    ///		</listheader>
    ///		<item>
    ///			<term>InputFileName</term>
    ///			<description>full path of the xml file to validate</description>
    ///		</item>
    ///	</list>
    ///	</remarks>
    public class XmlValidateStep : ITestStep
    {
        /// <summary>
        /// Execute the XmlValidateStep step 
        /// </summary>
        /// <param name='testConfig'>The Xml fragment containing the configuration for this test step</param>
        /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param>
        public void Execute(XmlNode testConfig, Context context)
        {
            string InputFileName = context.ReadConfigAsString(testConfig, "InputFileName");
            XmlNodeList schemaList = testConfig.SelectNodes("./SchemaList/SchemaFile");
            XmlSchemaSet schemaSet = new XmlSchemaSet();
            
            ArrayList arr = new ArrayList();
            string schemafilepath = "";
            string schemans = "";
            string filepathstr = "";
            string nsstr = "";

            for (int arrayindex = 0; arrayindex < schemaList.Count; arrayindex++)
            {
                filepathstr = string.Format("./*[local-name()='SchemaList']/*[local-name()='SchemaFile' and position() = {0}]", arrayindex + 1);
                nsstr = string.Format("./*[local-name()='SchemaList']/*[local-name()='SchemaFile' and position() = {0}]/@namespace", arrayindex + 1);

                schemafilepath = context.ReadConfigAsString(testConfig, filepathstr);
                schemans = context.ReadConfigAsString(testConfig, nsstr);
                schemaSet.Add(schemans, schemafilepath);
            }
            

            // Load XML document from input file
            try
            {
                SchemaValidator sv = new SchemaValidator(schemaSet);
                arr = sv.ValidateIt(InputFileName);
                context.Add("XmlValidateStepErrorCount", arr.Count.ToString(),true);
                if (arr.Count > 0)
                {
                    foreach (string valerr in arr)
                    {
                        context.LogInfo(valerr);
                    }
                }

            }
            //catch any exceptions from the try block
            catch (Exception ex)
            {
                context.LogException(ex);
                throw;
            }
            // doesn't matter what stream you send to context validator
            MemoryStream data = new MemoryStream(System.Text.Encoding.UTF8.GetBytes("hello"));
            XmlNode validationConfig = testConfig.SelectSingleNode("ValidationStep");
            context.ExecuteValidator(data, validationConfig);
        }

    }
}
